/*
 *  ofxJSTrueTypeFont
 *  openFrameworks
 *
 *  Created by Julien Gachadoat on 07/08/09.
 *  Copyright 2009 2Roqs. All rights reserved.
 *
 */

#include "ofxJSTrueTypeFont.h"
#include "js/ofxJSTrueTypeFont.cpp"

//--------------------------------------------------------------
ofxJSTrueTypeFont::ofxJSTrueTypeFont(){}
ofxJSTrueTypeFont::~ofxJSTrueTypeFont(){}
//--------------------------------------------------------------
void ofxJSTrueTypeFont::initialize(){
	ofxJSTrueTypeFont::JSInit	(ofxJSGetContext(), ofxJSGetGlobalObj());
}
//--------------------------------------------------------------
void ofxJSTrueTypeFont::finalize(){
}
//--------------------------------------------------------------
OFX_INST_DEFINE_JSFUNC_2(ofxJSTrueTypeFont,loadFont,string,int,m_ttf)
//--------------------------------------------------------------
OFX_INST_DEFINE_JSFUNC_5(ofxJSTrueTypeFont,loadFont,string,int,bool,bool,bool,m_ttf)
//--------------------------------------------------------------
OFX_INST_DEFINE_JSFUNC_1(ofxJSTrueTypeFont,setLineHeight,float,m_ttf)
OFX_INST_DEFINE_JSFUNC_0_RETURN(float,ofxJSTrueTypeFont,getLineHeight,m_ttf)
//--------------------------------------------------------------
OFX_INST_DEFINE_JSFUNC_1_RETURN(float,ofxJSTrueTypeFont,stringWidth,string,m_ttf)
OFX_INST_DEFINE_JSFUNC_1_RETURN(float,ofxJSTrueTypeFont,stringHeight,string,m_ttf)
//--------------------------------------------------------------
OFX_INST_DEFINE_JSFUNC_3(ofxJSTrueTypeFont,drawString,string,float,float,m_ttf)
//--------------------------------------------------------------
OFX_INST_DEFINE_JSFUNC_3(ofxJSTrueTypeFont,drawStringAsShapes,string,float,float,m_ttf)
//--------------------------------------------------------------
JSBool ofxJSTrueTypeFont::getStringBoundingBox(jsval* rval,string s,float x,float y){
	JSContext* cx = ofxJSGetContext();

	ofRectangle bounding = m_ttf.getStringBoundingBox(s,x,y);
	JSObject* jsBounding = JS_NewObject(cx, NULL, NULL, NULL);
	if (
		JS_DefineProperty(cx, jsBounding, "x",		float_TO_ofxJSValue(bounding.x),		NULL, NULL, JSPROP_READONLY) &&
		JS_DefineProperty(cx, jsBounding, "y",		float_TO_ofxJSValue(bounding.y),		NULL, NULL, JSPROP_READONLY) &&
		JS_DefineProperty(cx, jsBounding, "width",	float_TO_ofxJSValue(bounding.width),	NULL, NULL, JSPROP_READONLY) &&
		JS_DefineProperty(cx, jsBounding, "height", float_TO_ofxJSValue(bounding.height),	NULL, NULL, JSPROP_READONLY)
		){
	}

	*rval = OBJECT_TO_JSVAL(jsBounding);
	return JS_TRUE;
}

//--------------------------------------------------------------
JSBool ofxJSTrueTypeFont::getCharacterAsPoints(jsval* rval,int character){
	JSContext* cx = ofxJSGetContext();

	JSObject* jsChar			= JS_NewObject(cx,0,NULL,NULL);
	JSObject* jsArrayContours	= JS_NewArrayObject(cx,0,NULL);
	
	// defining char.contours (array)
	if (JS_TRUE == JS_DefineProperty(cx, jsChar, "contours", OBJECT_TO_JSVAL(jsArrayContours), NULL, NULL, JSPROP_READONLY))
	{
		ofTTFCharacter ofChar				= m_ttf.getCharacterAsPoints(character);
		vector<ofTTFContour>& contours		= ofChar.contours; 	
		vector<ofTTFContour>::iterator		contoursIt;
		vector<ofPoint>::iterator			ptsIt;

		int countContour=0;
		jsval jsvalContour;
		for (contoursIt = contours.begin(); contoursIt != contours.end(); ++contoursIt,++countContour)
		{
			ofTTFContour&	contour			= *contoursIt;
			JSObject*		jsContour		= JS_NewObject(cx,0,NULL,NULL);
			jsval			jsvalContour	= OBJECT_TO_JSVAL(jsContour);

			// char.contours[i] is an object
			if (JS_TRUE == JS_SetElement(cx, jsArrayContours, countContour, &jsvalContour))
			{
				JSObject* jsArrayPts	= JS_NewArrayObject(cx,0,NULL);
				if (JS_TRUE == JS_DefineProperty(cx, jsContour, "pts", OBJECT_TO_JSVAL(jsArrayPts), NULL, NULL, JSPROP_READONLY))
				{
					vector<ofPoint>& pts	= contour.pts; 	
					int countPts=0;
					for (ptsIt = pts.begin(); ptsIt != pts.end(); ++ptsIt,++countPts)
					{
						ofPoint&		pt				= *ptsIt;
						JSObject*		jsPt			= JS_NewObject(cx,0,NULL,NULL);
						jsval			jsvalPt			= OBJECT_TO_JSVAL(jsPt);

						JS_DefineProperty(cx, jsPt, "x", float_TO_ofxJSValue(pt.x),	NULL, NULL, JSPROP_READONLY);
						JS_DefineProperty(cx, jsPt, "y", float_TO_ofxJSValue(pt.y),	NULL, NULL, JSPROP_READONLY);
						JS_SetElement(cx, jsArrayPts, countPts, &jsvalPt);
						
					}
				}
			}
		}
	}

	*rval = OBJECT_TO_JSVAL(jsChar);
	
	return JS_TRUE;
}
